package cn.anc.httpcontrolutil;

import android.app.Activity;
import android.util.Log;

import java.io.File;
import java.io.IOException;

import androidx.annotation.Nullable;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;
import okio.Source;

/**
 * Created by baobaoding on 2017/5/6.
 */

public class HttpFirmwareUpload extends Thread {
    private static String TAG = HttpFirmwareUpload.class.getSimpleName();
    private OkHttpClient mOkHttpClient = new OkHttpClient();
    private String upload_url = null;
    private String upload_key = null;
    private String local_path = null;
    private HttpFileUploadListener listener = null;
    private Activity activity = null;

    public interface HttpFileUploadListener {
        void onStart();
        void onError(String error);
        void onUploadProgress(float progress);
        void onSuccess();
    }


    private void guiStart() {
        if (listener != null && activity != null) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    listener.onStart();
                }
            });
        }
    }
    private void guiSuccess() {
        if (listener != null && activity != null) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    listener.onSuccess();
                }
            });
        }
    }
    private void guiError(final  String error) {
        if (listener != null && activity != null) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    listener.onError(error);
                }
            });
        }
    }
    private void guiOnProgress(final float progress) {
        if (listener != null && activity != null) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    listener.onUploadProgress(progress);
                }
            });
        }
    }

    public static class HttpFileUploadEvent {
        public static final int HTTP_FILE_UPLOAD_FAIL = 2;
    }

    public class HttpFileUploadResult {
        public int rval = -1;
        public String video_url = null;
        public String thumb_url = null;
        public String md5 = null;
    }



    public HttpFirmwareUpload(Activity _activity, String _upload_url, String _upload_key, String _local_path, HttpFileUploadListener _listener) {
        activity = _activity;
        upload_url = _upload_url;
        upload_key = _upload_key;
        local_path = _local_path;
        listener = _listener;
    }

    @Override
    public void run() {
        super.run();
        try {
            File file = new File(local_path);
            String filename = file.getName();
            guiStart();
            ProgressRequestBody progressRequestBody = new ProgressRequestBody(MediaType.parse("application/octet-stream"), file);
            RequestBody body = new MultipartBody
                    .Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart(upload_key, filename, progressRequestBody)
                    .build();
            Request request = new Request.Builder().url(upload_url).post(body).build();
            Response response = mOkHttpClient.newCall(request).execute();
            Log.d(TAG, "upload code:" + response.code());
            if (response == null || response.code() != 200) {
                if (response != null) {
                    Log.d(TAG, "upload code:" + response.code());
                }
                guiError("error:code!=200");
                return;
            }
            Log.d(TAG, "upload: ok");
            Log.d(TAG, "response:"+response.body().string());
            guiSuccess();
        } catch (Exception ex) {
            Log.e(TAG, "error: " + ex.getMessage());
            guiError(ex.getMessage());
        }
    }



    private class ProgressRequestBody extends RequestBody {
        private MediaType mediaType = null;
        private File file = null;
        private BufferedSink bufferedSink;
        private RequestBody requestBody;
        public ProgressRequestBody(MediaType _mediatype, File _file) {
            this.mediaType = _mediatype;
            this.file = _file;
        }

        @Nullable
        @Override
        public MediaType contentType() {
            return mediaType;
        }

        @Override
        public long contentLength() throws IOException {
            return file.length();
        }

        @Override
        public void writeTo(BufferedSink sink) throws IOException {
            Source source = Okio.source(file);
//            sink.writeAll(source);
            Buffer buf = new Buffer();
            long totalBytes = contentLength();
            long writeBytes = 0;
            for (long readCount; (readCount = source.read(buf, 8192)) != -1;) {
                sink.write(buf, readCount);
                writeBytes += readCount;
                float f = (float) writeBytes / totalBytes;
                //回调
                Log.e(TAG, "writeBytes4: " + writeBytes + ",progress:" + (writeBytes * 100) / totalBytes);
                guiOnProgress(f);
                //listener.onProgress(contentLength(), remaining -= readCount, remaining == 0);
            }
    }

    private Sink sink(BufferedSink sink) {

        return new ForwardingSink(sink) {
            long bytesWritten = 0L;
            long contentLength = 0L;
            @Override
            public void write(Buffer source, long byteCount) throws IOException {
                super.write(source, byteCount);
                if (contentLength==0){
                    contentLength = contentLength();
                }
                bytesWritten += byteCount;
                float f = (float) bytesWritten / contentLength;
                //回调
                Log.e(TAG, "writeBytes4: " + bytesWritten + ",progress:" + (bytesWritten * 100) / contentLength);
                guiOnProgress((int) (100 * f));

            }
        };
    }

    }
}
